package com.tsyz.servlet.dao.impl;

import com.tsyz.servlet.dao.UserDao;
import com.tsyz.servlet.domain.bo.req.UserFindByUserNameReqBO;
import com.tsyz.servlet.domain.bo.req.UserGetUserByIdReqBO;
import com.tsyz.servlet.domain.bo.req.UserUpdateUserReqBO;
import com.tsyz.servlet.domain.bo.resq.UserFindAllRespBO;
import com.tsyz.servlet.domain.bo.resq.UserFindByUserNameRespBO;
import com.tsyz.servlet.domain.bo.resq.UserGetUserByIdRespBO;
import com.tsyz.servlet.domain.mapstruct.UserFindAllRespBOMapper;
import com.tsyz.servlet.domain.mapstruct.UserFindByUserNameRespBOMapper;
import com.tsyz.servlet.domain.mapstruct.UserGetUserByIdRespBOMapper;
import com.tsyz.servlet.domain.po.UserPO;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

@Repository
public class UserDaoImpl implements UserDao {

    // 使用内存Map模拟数据库存储
    private final Map<Long, UserPO> userStore = new ConcurrentHashMap<>();
    private final AtomicLong idGenerator = new AtomicLong(1); // ID生成器

    // 初始化一些模拟数据
    public UserDaoImpl() {
        LocalDateTime now = LocalDateTime.now();
        UserPO admin = UserPO.builder()
                .id(idGenerator.getAndIncrement())
                .name("管理员")
                .userName("admin")
                .password("admin123")
                .email("admin@example.com")
                .age(30)
                .createTime(now)
                .updateTime(now)
                .createPin("system")
                .updatePin("system")
                .isDelete(0)
                .build();
        userStore.put(admin.getId(), admin);

        UserPO testUserPO = UserPO.builder()
                .id(idGenerator.getAndIncrement())
                .name("测试用户")
                .userName("test")
                .password("test123")
                .email("test@example.com")
                .age(25)
                .createTime(now)
                .updateTime(now)
                .createPin("system")
                .updatePin("system")
                .isDelete(0)
                .build();
        userStore.put(testUserPO.getId(), testUserPO);
    }

    @Override
    public List<UserFindAllRespBO> findAll() {
        // 返回所有未删除的用户
        List<UserPO> list = userStore.values().stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return UserFindAllRespBOMapper.INSTANCE.poToBo(list);
    }

    @Override
    public UserGetUserByIdRespBO getUserById(UserGetUserByIdReqBO reqBo) {
        // 只返回未删除的用户
        UserPO userPo = userStore.get(reqBo.getId());
        return UserGetUserByIdRespBOMapper.INSTANCE.poToBo(userPo);
    }


    @Override
    public UserPO updateUser(UserUpdateUserReqBO reqBo) {
        if (reqBo == null || reqBo.getId() == null) {
            return null;
        }

        UserPO userPo = userStore.get(reqBo.getId());
        if (userPo == null || userPo.getIsDelete() == 1) {
            return null;
        }

        // 更新用户信息，保留创建信息
        UserPO updatedUserPO = userPo.toBuilder()
                .name(reqBo.getName())
                .userName(reqBo.getUserName())
                .password(reqBo.getPassword())
                .email(reqBo.getEmail())
                .age(reqBo.getAge())
                .updateTime(LocalDateTime.now())
                .updatePin("system") // 这里应该是当前登录用户
                .build();

        userStore.put(updatedUserPO.getId(), updatedUserPO);
        return updatedUserPO;
    }

    @Override
    public UserPO createUser(UserPO userPO) {
        if (userPO == null) {
            return null;
        }

        // 为新用户设置ID和其他必要字段
        UserPO newUserPO = userPO.toBuilder()
                .id(idGenerator.getAndIncrement())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .createPin("system") // 这里应该是当前登录用户
                .updatePin("system") // 这里应该是当前登录用户
                .build();

        userStore.put(newUserPO.getId(), newUserPO);
        return newUserPO;
    }

    @Override
    public boolean deleteUser(UserGetUserByIdReqBO reqBo) {
        Long id = reqBo.getId();
        UserPO userPO = userStore.get(id);
        if (userPO == null) {
            return false;
        }

        userStore.remove(id);
        return true;
    }

    /**
     * 根据用户名查找用户
     *
     * @param reqBO 要查找的用户名，不能为空
     * @return 匹配的用户对象，如果找不到则返回null
     * @throws IllegalArgumentException 如果userName为null或空字符串
     */
    @Override
    public UserFindByUserNameRespBO findByUserName(UserFindByUserNameReqBO reqBO) {
        // 参数校验
        if (reqBO == null || reqBO.getUserName() == null || reqBO.getUserName().trim().isEmpty()) {
            throw new IllegalArgumentException("用户名不能为空");
        }

        // 遍历Map查找匹配用户名的用户
        for (UserPO userPo : userStore.values()) {
            if (userPo.getUserName().equals(reqBO.getUserName())) {
                return UserFindByUserNameRespBOMapper.INSTANCE.poToBo(userPo);
            }
        }
        return null;
    }

    /**
     * 校验密码是否有效（验证两次输入一致且符合安全规则）
     *
     * @param password  第一次输入的密码
     * @param password1 第二次输入的密码（确认密码）
     * @return true如果密码有效（两次输入一致且符合安全要求），否则返回false
     * @throws IllegalArgumentException 如果任一密码为null或空
     */
    @Override
    public boolean checkPassword(String password, String password1) {
        // 基础校验
        if (password == null || password1 == null) {
            throw new IllegalArgumentException("密码不能为null");
        }

        // 去除前后空格后检查是否为空
        password = password.trim();
        password1 = password1.trim();
        if (password.isEmpty() || password1.isEmpty()) {
            throw new IllegalArgumentException("密码不能为空");
        }

        // 检查两次输入是否一致
        return password.equals(password1);

        // 密码复杂度检查（可根据需求调整）
//        if (password.length() < 8) {
//            return false;
//        }

        // 检查是否包含数字和字母
//        boolean hasLetter = false;
//        boolean hasDigit = false;
//        for (char c : password.toCharArray()) {
//            if (Character.isLetter(c)) {
//                hasLetter = true;
//            } else if (Character.isDigit(c)) {
//                hasDigit = true;
//            }
//        }
    }
}